function add1(str) {
  return str + 1;
}
function add2(str) {
  return str + 2;
}
function add3(str) {
  return str + 3;
}

// console.log(add1(add2(add3('aa'))));

/**
 * 解析：reduceRight从数组最后一项开始，向前遍历，每次返回一个函数
 * 第一次执行：a=add2, b=add1 => 返回值：(...args) => add2(add1(...args))
 * 第二次执行：a=(...args) => add2(add1(...args)), b=add3 => 返回值：(...args) => add3(add2(add1(...args)))
 */
const flowed = (...args) => {
  // 如果函数只有一个，直接返回
  if (args.length === 1) return args[0];

  // 若函数有多个则走下面逻辑
  // reduceRight从数组最后一项开始，向前遍历
  return args.reduceRight(
    (a, b) =>
      (...args) =>
        a(b(...args))
  );
};

console.log(flowed(add3, add2, add1)('aa'));

// 从右向左合并函数
const flowedRight = (...args) => {
  if (args.length === 1) return args[0];
  return args.reduce(
    (a, b) =>
      (...args) =>
        a(b(...args))
  );
};
console.log(flowedRight(add3, add2, add1)('bb'));
